package com.example.demo.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

public class ReflectionUtils {

    /**
     * 通过反射将object转map
     */
    public static Map<String, Object> object2Map(Object obj) {
        Map<String, Object> map;
        try {
            Field[] fields = obj.getClass().getDeclaredFields();
            int fieldSize = fields.length;
            if (fieldSize > 0) {
                map = new HashMap<>(fieldSize);
                for (int i = 0; i < fieldSize; i++) {
                    Field field = fields[i];
                    makeAccessible(field);
                    map.put(field.getName(), field.get(obj));
                }
                return map;
            }
        } catch (IllegalAccessException e) {
        }
        map = new HashMap<>(16);
        return map;
    }

    /**
     * 直接设置对象属性值,忽视private/protected修饰符
     */
    public static void setFieldValue(final Object object, final String fieldName, final Object value) {
        Field field = getDeclaredField(object, fieldName);

        if (field == null) {
            throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
        }

        makeAccessible(field);

        try {
            field.set(object, value);
        } catch (IllegalAccessException e) {

        }
    }

    /**
     * 取对象的DeclaredField
     */
    protected static Field getDeclaredField(final Object object, final String fieldName) {
        for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                return superClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
            }
        }
        return null;
    }

    /**
     * 设置属性的访问权限
     */
    protected static void makeAccessible(final Field field) {
        if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) {
            field.setAccessible(true);
        }
    }

}

